class MyClass():
    '''A simple exampel class'''
    i = 12345

    def __init__(self, realpart, imagpart):
        self.real = realpart
        self.imag = imagpart

    def f(self):
        return self.real + 'hello'


x = MyClass('huhx', 'linux')
print(x.real, x.imag, x.i, MyClass.i)  # MyClass.real会报错
print(MyClass.__doc__, x.__doc__)  # A simple exampel class
print(MyClass.f(x), x.f())  # huhxhello huhxhello


class Dog():
    # tricks = []

    def __init__(self):
        self.tricks = []

    def add_tricks(self, trick):
        self.tricks.append(trick)
d = Dog()
d.add_tricks('roll over')
e = Dog()
e.add_tricks('play dead')
print(d.tricks, e.tricks) # ['roll over', 'play dead'] ['roll over', 'play dead']


# Any function object that is a class attribute defines a method for instances of that class. It is not necessary that the function definition is textually enclosed in the class definition
def f1(self, x, y):
    return min(x, y)

class C():
    f = f1
    def g(self):
        return 'hello world'

    h = g

classC = C()
print(C.f(classC, 2, 45), classC.f(2, 45)) # 2 2
print(classC.h()) # hello world
classC.h = 'hello abc'
print(classC.g(), classC.h) # hello world hello abc


class Student(object):
    def __init__(self, name, score):
        self.__name = name
        self.__score = score
        self._name = name

    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

bart = Student('Bart Simpson', 59)
# print(bart._name) # AttributeError: 'Student' object has no attribute '_name'
print(bart._Student__name)
print(bart._name) # 虽然我可以被访问，但是，请把我视为私有变量，不要随意访问
print(type(bart)) # <class '__main__.Student'>
print(isinstance(bart, Student), issubclass(Student, object)) # True True



class Employee:
    pass

john = Employee()  # Create an empty employee record

# Fill the fields of the record
Employee.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000
print(john.name) # John Doe


for ele in [1, 2, 3]:
    print(ele, end=' ')
print()

s = 'abc'
it = iter(s)
print(next(it), next(it), next(it), end=' ')
print()

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

for char in reverse('huhx'):
    print(char, end=' ')
print()

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

rev = Reverse('linux')
for char in rev:
    print(char, end=' ')

# 1 2 3
# a b c
# x h u h
# x u n i l



